﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Permissions;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Net;
using RoboRace_Shared;
using NetSockets;
using System.Threading;
namespace RoboRace_Server
{
    class Program
    {
        Boolean isOver;
        Boolean isStartGame;
        Game robotGame;
        NetObjectServer tcpServer;
        int numPlayers;

        static void Main(string[] args)
        {
            Program game = new Program();
            game.StartTCPServer(2, IPAddress.Parse("127.0.0.1"), 3333);
            game.StartGameLoop();
        }

        private void StartTCPServer(int playerCount, IPAddress serverAddress, int serverPort)
        {
            isStartGame = false;
            numPlayers = playerCount;
            tcpServer = new NetObjectServer();
            tcpServer.OnStarted += new NetStartedEventHandler(tcpServer_OnStarted);
            tcpServer.OnClientConnected += new NetClientConnectedEventHandler(tcpServer_OnClientConnected);
            tcpServer.OnClientAccepted += new NetClientAcceptedEventHandler(tcpServer_OnClientAccepted);
            tcpServer.OnClientDisconnected += new NetClientDisconnectedEventHandler(tcpServer_OnClientDisconnected);
            tcpServer.OnReceived += new NetClientReceivedEventHandler<NetObject>(tcpServer_OnReceived);
            tcpServer.Start(serverAddress, serverPort, 30);
        }

        void tcpServer_OnClientDisconnected(object sender, NetClientDisconnectedEventArgs e)
        {
            robotGame.Disconnect(e.Guid);
        }

        void tcpServer_OnClientAccepted(object sender, NetClientAcceptedEventArgs e)
        {
            tcpServer.DispatchTo(e.Guid, new NetObject("Guid", e.Guid));
        }

        void tcpServer_OnClientConnected(object sender, NetClientConnectedEventArgs e)
        {
            Console.WriteLine("Client Connected!");
        }

        void tcpServer_OnStarted(object sender, NetStartedEventArgs e)
        {
            Console.WriteLine("TCP socket server started.");
        }

        void tcpServer_OnReceived(object sender, NetClientReceivedEventArgs<NetObject> e)
        {
            switch (e.Data.Name)
            {
                case "Command":
                    break;
                case "Join":
                    Player recPlayer = (Player)e.Data.Object;
                    robotGame.Join(recPlayer);
                    break;
                case "Move":
                    break;
                case "Push":
                    break;
                case "Rotate":
                    break;
            }
        }

        protected void StartGameLoop()
        {
            robotGame = new Game(numPlayers);
            robotGame.OnGameStarted += new GameStarted(robotGame_OnGameStarted);
            robotGame.OnGameStopped += new GameStopped(robotGame_OnGameStopped);
            robotGame.OnGameOver += new GameOver(robotGame_OnGameOver);
            robotGame.OnPlayerJoin += new PlayerJoin(robotGame_OnPlayerJoin);
            robotGame.OnPlayerNoJoin += new PlayerNoJoin(robotGame_OnPlayerNoJoin);
            robotGame.OnPlayerRemoved += new PlayerRemoved(robotGame_OnPlayerRemoved);
            robotGame.OnRobotsUpdated += new RobotsUpdated(robotGame_OnRobotsUpdated);

           /* while (isStartGame == false)
            {
                
                Console.WriteLine("Waiting for game to start...");
                Thread.Sleep(5000);
            }

            isOver = false;
            while (isOver == false)
            {
                
                Console.WriteLine("Game in progress...");
                Thread.Sleep(10000);
            }*/
        }

        void robotGame_OnPlayerNoJoin(Player player)
        {
            NetObject obj = new NetObject("Notification", "GAME FULL!");
            tcpServer.DispatchTo(player.Guid, obj);
        }

        void robotGame_OnRobotsUpdated(List<Robot> robots)
        {
            NetObject obj = new NetObject("Robots", robots);
            tcpServer.DispatchAll(obj);
        }

        void robotGame_OnPlayerRemoved(Guid guid)
        {
            robotGame.Disconnect(guid);
            Console.WriteLine("Player disconnected: {0}", guid);
            
        }

        private void robotGame_OnGameStopped(string message)
        {
            if (isOver == false)
            {
                isOver = true;
                Console.WriteLine(message);
                NetObject obj = new NetObject("Notification", "Game Stopped.");
                tcpServer.DispatchAll(obj);
            }
        }

        private void robotGame_OnGameStarted(string message)
        {
            if (isStartGame == false)
            {
                Console.WriteLine(message);
                isStartGame = true;
                NetObject obj = new NetObject("Notification", "Game Started.");
                tcpServer.DispatchAll(obj);
            }
        }

        private void robotGame_OnGameOver(string message)
        {
            Console.WriteLine("Game Over!");
            isOver = true;
        }

        private void robotGame_OnPlayerJoin(Player player)
        {
            NetObject obj = new NetObject("Board", robotGame.Board);
            tcpServer.DispatchTo(player.Guid, obj);
        }
    }
}
